import sys
import os
from sqlalchemy import StaticPool
from sqlalchemy.ext.asyncio import create_async_engine
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.ext.asyncio import async_sessionmaker

# 添加路径到 sys.path
f1 = os.path.dirname(__file__)
sys.path.append(f1)
f2 = os.path.dirname(f1)
sys.path.append(f2)

class TestS3:
    bucket_list = []
    object_list = []

    def get_bucket_list(self) -> list:
        return self.bucket_list

    def create_bucket(self, bucket_name: str) -> bool:
        self.bucket_list.append(bucket_name)
        return True

    def delete_bucket(self, bucket_name: str) -> bool:
        if bucket_name in self.bucket_list:
            self.bucket_list.remove(bucket_name)
            return True
        return False

    def check_bucket_exists(self, bucket_name: str) -> bool:
        return bucket_name in self.bucket_list

    def get_object_tags(self, bucket: str, key: str) -> dict | None:
        if key in self.object_list:
            return {"tag": "test"}

    def get_object_metadata(self, bucket: str, key: str) -> dict | None:
        if key in self.object_list:
            return {"size": 1024, "etag": "test-etag"}
        return None

    def check_exists(self, bucket: str, key: str) -> bool:
        return key in self.object_list

    def presigned_upload_url(
        self, bucket: str, key: str, expires_in: int = 60
    ) -> str | None:
        return "http://example.com/presigned-upload-url"

    def presigned_download_url(
        self, bucket: str, key: str, expires_in: int = 60
    ) -> str | None:
        return "http://example.com/presigned-download-url"


# 创建异步测试数据库
# SQLALCHEMY_DATABASE_URL = "sqlite+aiosqlite:///:memory:"
SQLALCHEMY_DATABASE_URL = "sqlite+aiosqlite:///test.db"
engine = create_async_engine(
    SQLALCHEMY_DATABASE_URL,
    connect_args={"check_same_thread": False},
)
TestAsyncSessionLocal = async_sessionmaker(
    bind=engine, 
    class_=AsyncSession, 
    expire_on_commit=False,
    autocommit=False, 
    autoflush=False
)
    
# 重写依赖项为异步函数
async def override_get_db():
    """异步测试数据库会话依赖"""
    async with TestAsyncSessionLocal() as session:
        try:
            yield session
        finally:
            await session.close()
    
# 导入所有模型以确保 Base.metadata 包含所有表定义
from basic.models import (
    Base,
    LogicalRepository,
    LogicalEntry,
    LogicalFile,
    LogicalVersion,
    RelationRepoEntry,
    RelationEntryFile,
    RelationFileVersion,
    User,
    Resource,
    Policy
)

async def generate_mock_data(sql_statements: list | None = None):
    """异步初始化测试数据库"""
    print("Initializing test database...")
    # 创建数据库表
    async with engine.begin() as conn:
        # 确保先清空
        await conn.run_sync(Base.metadata.drop_all)
        # 创建所有表
        await conn.run_sync(Base.metadata.create_all)
        
    if sql_statements:
        async with engine.begin() as conn:
            for stmt in sql_statements:
                await conn.execute(stmt)
